/*************************************************************************
	> File Name: server.c
	> Author: yuxintao
	> Mail: 1921056015@qq.com 
	> Created Time: 2022年03月29日 星期二 09时24分56秒
 ************************************************************************/

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>

int serverport = 8888;
char *path = "./server.txt";

int sockfd = -1;
int fd = -1;
FILE* fp = NULL;

char receive_buff[1024];

int running = 1;

void son(int fd) {
	fp = fopen(path, "a+");
	if (fp == NULL) {
		perror("fopen");
		return;
	}
	while (running) {
		int sum = 0;
		while (running) {
			memset(receive_buff, 0, 1024);
			int len = recv(fd, receive_buff, 1024, 0);
			if (strncmp(receive_buff, "close", 4) == 0) {
				fclose(fp);
				close(fd);
				return;
			} 
			char *p = NULL, *pos = receive_buff;
			while ((p = strstr(pos, "$")) != NULL) {
				*p = '\0';
				sum += p - pos;
				fputs(pos, fp);
				send(fd, pos, p - pos, 0);
				pos = p + 1;
			}
			if (strncmp(pos, "over", 4) == 0) {
				memset(receive_buff, 0, 1024);
				sprintf(receive_buff, "receive %d byte\n", sum);
				fputs(receive_buff, fp);
				send(fd, receive_buff, strlen(receive_buff), 0);
				break;
			}
		}
	}
}

void sigint(int sign) {
	running = 0;
	close(sockfd);
	exit(0);
}

int main()
{
	signal(SIGINT, sigint);
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == -1) {
		perror("sockfd");
		return 1;
	}
	struct sockaddr_in server;
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = htonl(INADDR_ANY);
	server.sin_port = htons(serverport);

	if (bind(sockfd, (struct sockaddr*)&server, sizeof(struct sockaddr)) < 0) {
		perror("bind");
		return 1;
	}
	listen(sockfd, 3);

	while (running) {
		struct sockaddr_in client;
		int length = sizeof(struct sockaddr);
		fd = accept(sockfd, (struct sockaddr*)&client, &length);
		if (fd == -1) {
			perror("accept");
			return 1;
		}
		printf("connect.....\n");
		fflush(stdout);
		pid_t t = fork();
		if (t == 0) {
			close(sockfd);
			son(fd);
			break;
		} else {
			close(fd);
		}
	}
	return 0;
}
